<?php

	// +----------------------------------------------------------------------
	// | 用户签到管理
	// +----------------------------------------------------------------------
	// | Copyright (c) 2015-2024 http://www.yicmf.com, All rights reserved.
	// +----------------------------------------------------------------------
	// | Author: 微尘 <yicmf@qq.com>
	// +----------------------------------------------------------------------

	namespace app\event\ucenter;

	use app\model\ucenter\User as UserModel;
	use app\model\ucenter\UserSign as UserSignModel;
	use app\event\ucenter\UserPoint as UserPointEvent;
	use app\event\ucenter\UserExperience as UserExperienceEvent;
	use app\common\event\Base;
	use think\facade\Db;
	use think\Exception;
	use think\facade\Config;

	class UserSign extends Base
	{
		/**
		 * 用户签到状态
		 * @param UserModel $user
		 * @return mixed
		 * @author  : 微尘 <yicmf@qq.com>
		 */
		public function status($user)
		{
			// 是否今天已经签到
			if (UserSignModel::where('user_id', $user['id'])->whereTime('create_time', 'today')->find()) {
				$sign['signed'] = 1;
				$sign['sign_day'] = $user['sign_day'];
			} else {
				$sign['signed'] = 0;
				// 是否断签
				if (UserSignModel::where('user_id', $user['id'])->whereTime('create_time', 'yesterday')->find()) {
					$sign['sign_day'] = $user['sign_day'];
				} else {
					$sign['sign_day'] = 0;
				}
			}
			// 邀请新人
			$sign['invite_new_user'] = Config::get('ucenter.invite_new_user');
			$sign['get_point'] = $this->_getPoint($sign['sign_day']);
			$sign['point'] = $user['point'];
			$sign['arr'] = $this->_getNextAttr($sign['sign_day']);
			$sign['tips'] = $sign['signed']?('明天签到获取积分' . $sign['get_point']):('今日签到获取积分' . $sign['get_point']);
			$sign['rule'] = '第1天获得5积分；
连续2-5天，每天获得10积分；
连续6-10天，每天获得15积分；
连续11-19天，每天获得20积分；
连续19天以上，每天获得25积分；
之后每满30天额外奖励' . Config::get('ucenter.sign_month_point') . '积分。';
			$data['data'] = $sign;
			$data['code'] = 0;
			return $data;
		}


		/**
		 * 用户签到
		 * @param array $param
		 * @param UserModel $user
		 * @param int $from
		 * @return mixed
		 * @author  : 微尘 <yicmf@qq.com>
		 */
		public function in($param, $user, $from = 0)
		{
			// 开启事务
			try {
				Db::startTrans();
				// 并发行锁表
				$user = UserModel::where('id', $user['id'])->lock(true)->find();
				// 是否今天已经签到
				if (UserSignModel::where('user_id', $user['id'])->whereTime('create_time', 'today')->find()) {
					throw new Exception('今天已经签到');
				}
				if ($user['sign_day'] && UserSignModel::where('user_id', $user['id'])->whereTime('create_time', 'yesterday')->find()) {
					// 确认昨天是否签到;
					$user['sign_day'] = $user['sign_day'] + 1;
				} else {
					$user['sign_day'] = 1;
				}
				$sign = [];
				$sign['from'] = $from;
				$sign['user_id'] = $user['id'];
				$sign['sign_day'] = $user['sign_day'];
				$sign['level'] = UserSignModel::getLevel($user['sign_day']);
				$sign['score'] = $this->_getPoint($user['sign_day']);
				$sign['signed'] = 1;
				$sign = UserSignModel::create($sign);
				if (!$sign) {
					throw new Exception('签到失败');
				}
				// 经验
				$log = [];
				$log['change_code'] = 'user_sign';
				$log['experience'] = $sign['score'];
				$log['relation_id'] = $sign['id'];
				UserExperienceEvent::change($log, $user);
				// 积分
				$log = [];
				$log['change_code'] = 'user_sign';
				$log['point'] = $sign['score'];
				$log['relation_id'] = $sign['id'];
				UserPointEvent::change($log, $user);
				$param['level'] = $sign['level'];
				//记录行为
				Action::log('user_sign', $user, $param);
				// 提交事务
				Db::commit();
				$next['next_point'] = $this->_getPoint($sign['sign_day'] + 1);
				$next['signed'] = 1;
				$next['sign_day'] = $sign['sign_day'];
				$next['get_point'] = $sign['score'];
				$next['point'] = $user['point'];
				$next['tips'] = '明天签到即将获取' . $next['next_point'] . '个积分';
				$data['code'] = 0;
				$data['data'] = $next;
				$data['message'] = '签到成功';
			} catch (Exception $e) {
				// 回滚事务
				Db::rollback();
				$data['code'] = 1;
				$data['message'] = $e->getMessage();
			}
			return $data;
		}


		protected function _getPoint($day)
		{
			$level = UserSignModel::getLevel($day);

			return 5 * $level;
		}

		/**
		 * 获取未来几天的积分情况
		 * @param $day
		 * @return array
		 */
		protected function _getNextAttr($day)
		{

			$arr = [];
			$day = $day == 0 ? 1 : $day;
			for ($x = 0; $x < 7; $x++) {
				$arr[] = [
					'day' => $day,
					'point' => $this->_getPoint($day)
				];
				$day++;
			}
			return $arr;
		}
	}
